package com.itheima.server.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itheima.commons.template.AipFaceTemplate;
import com.itheima.commons.template.HuanXinTemplate;
import com.itheima.commons.template.OssTemplate;
import com.itheima.domain.db.Question;
import com.itheima.domain.db.Settings;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.CommonLikeUser;
import com.itheima.domain.vo.*;
import com.itheima.dubbo.api.*;
import com.itheima.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 阿鹏
 * @date 2021/1/24 21:11
 */
@Service
public class UserInfoService {

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private UserApi userApi;

    @Reference
    private SettingsApi settingsApi;
    @Reference
    private UserLikeApi userLikeApi;
    @Reference
    private FriendApi friendApi;

    @Reference
    private BlackListApi blackListApi;

    @Reference
    private QuestionApi questionApi;

    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public User findUserByToken(String token) {
        String userJson = redisTemplate.opsForValue().get("TOKEN_" + token);
        if (userJson == null) {
            return null;
        }
        User user = JSON.parseObject(userJson, User.class);
        redisTemplate.opsForValue().set("TOKEN_" + token, userJson, Duration.ofHours(1));
        return user;
    }

    public ResponseEntity findUserInfo(Long id) {
        UserInfo userInfo = userInfoApi.findById(id);
        UserInfoVo vo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo, vo);
        if (userInfo.getAge() != null) {
            vo.setAge(String.valueOf(userInfo.getAge()));
        }
        return ResponseEntity.ok(vo);
    }

    public ResponseEntity updateUserInfo(UserInfo userInfo) {
        userInfo.setId(UserHolder.getUserId());
        userInfoApi.update(userInfo);
        return ResponseEntity.ok(null);
    }

    public ResponseEntity updateHeader(MultipartFile headPhoto) throws IOException {
        User user = UserHolder.getUser();
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        if (!detect) {
            return ResponseEntity.status(500).body(ErrorResult.faceDetectFailed());
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        String path = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        userInfo.setAvatar(path);
        userInfoApi.update(userInfo);
        return ResponseEntity.ok(null);
    }

    public ResponseEntity getSettings() {
        User user = UserHolder.getUser();
        Question question = questionApi.findByUserId(user.getId());
        Settings settings = settingsApi.findByUserId(user.getId());

        SettingsVo vo = new SettingsVo();
        if (question != null) {
            vo.setStrangerQuestion(question.getTxt());
        }
        if (settings != null) {
            BeanUtils.copyProperties(settings, vo);
        }
        vo.setPhone(user.getMobile());
        return ResponseEntity.ok(vo);
    }

    public ResponseEntity getBlackList(Integer page, Integer pageSize) {
        User user = UserHolder.getUser();
        IPage<UserInfo> iPage = blackListApi.findByUserId(page, pageSize, user.getId());
        PageResult<UserInfo> pageResult = new PageResult<>();
        pageResult.setPage(page);
        pageResult.setCounts((int) iPage.getTotal());
        pageResult.setPages((int) iPage.getPages());
        pageResult.setPagesize(pageSize);
        pageResult.setItems(iPage.getRecords());
        return ResponseEntity.ok(pageResult);
    }

    public ResponseEntity removeFromBlacklist(Long blackUserId) {
        Long userId = UserHolder.getUserId();
        blackListApi.delete(userId, blackUserId);
        return ResponseEntity.ok(null);
    }

    public ResponseEntity saveQuestions(String content) {
        User user = UserHolder.getUser();
        Question question = questionApi.findByUserId(user.getId());
        if (question == null) {
            question = new Question();
            question.setUserId(user.getId());
            question.setTxt(content);
            questionApi.save(question);
        } else {
            question.setTxt(content);
            questionApi.update(question);
        }
        return ResponseEntity.ok(null);
    }

    public ResponseEntity saveSettings(Settings submitSetting) {
        User user = UserHolder.getUser();
        Settings originSetting = settingsApi.findByUserId(user.getId());
        if (originSetting == null) {
            submitSetting.setUserId(user.getId());
            settingsApi.save(submitSetting);
        } else {
            submitSetting.setId(originSetting.getId());
            submitSetting.setUserId(originSetting.getUserId());
            settingsApi.update(submitSetting);
        }
        return ResponseEntity.ok(null);
    }

    public ResponseEntity sendVerificationCode() {
        User user = UserHolder.getUser();
        String mobile = user.getMobile();
        String code = "123456";
        redisTemplate.opsForValue().set("CODE_" + mobile, code, Duration.ofMinutes(5));
        return ResponseEntity.ok(null);
    }

    public ResponseEntity checkVerificationCode(String verificationCode) {
        User user = UserHolder.getUser();
        String code = redisTemplate.opsForValue().get("CODE_" + user.getMobile());
        boolean flag;
        if (code == null || !code.equals(verificationCode)) {
            flag = false;
        } else {
            flag = true;
            redisTemplate.delete("CODE_" + user.getMobile());
        }

        Map<String, Object> map = new HashMap<>();
        map.put("verification", flag);
        return ResponseEntity.ok(map);
    }

    public ResponseEntity savePhone(String phone) {
        User user = UserHolder.getUser();
        user.setMobile(phone);
        userApi.update(user);
        return ResponseEntity.ok(null);
    }

    public ResponseEntity findLikeLoveFriendCounts() {
        Long userId = UserHolder.getUserId();

        // 调用api直接查询
        long likeCount = userLikeApi.queryLikeCount(userId);
        long fansCount = userLikeApi.queryFansCount(userId);
        long friendsCount = userLikeApi.queryFriendsCount(userId);

        // 封装返回数据
        Map<String, Object> map = new HashMap<>();
        map.put("loveCount", likeCount);
        map.put("fanCount", fansCount);
        map.put("eachLoveCount", friendsCount);
        return ResponseEntity.ok(map);
    }

    public ResponseEntity findUserLikeList(Integer type, int page, int pagesize) {
        Long userId = UserHolder.getUserId();
        PageResult<CommonLikeUser> pageResult = null;
        switch (type) {
            case 1:
                pageResult = userLikeApi.queryFriendsList(userId, page, pagesize);
                break;
            case 2:
                pageResult = userLikeApi.queryLikeList(userId, page, pagesize);
                break;
            case 3:
                pageResult = userLikeApi.queryFansList(userId, page, pagesize);
                break;
            case 4:
                pageResult = userLikeApi.findVisitorList(userId, page, pagesize);
                break;
            default:
                System.out.println("未知数据类型:" + type);
        }

        List<CommonLikeUserVO> voList = new ArrayList<>();
        for (CommonLikeUser user : pageResult.getItems()) {
            CommonLikeUserVO vo = new CommonLikeUserVO();

            // 查询的都是其他人
            UserInfo userInfo = userInfoApi.findById(user.getTargetUserId());
            BeanUtils.copyProperties(userInfo, vo);
            vo.setMatchRate(user.getScore().intValue());
            vo.setAlreadyLove(false);
            voList.add(vo);
        }

        // 构造返回值
        PageResult<CommonLikeUserVO> voPageResult = new PageResult<>();
        BeanUtils.copyProperties(pageResult, voPageResult);
        voPageResult.setItems(voList);
        return ResponseEntity.ok(voPageResult);
    }

    public ResponseEntity likeFans(Long fansId) {
        // 删除粉丝对当前用户的喜欢
        userLikeApi.delete(fansId, UserHolder.getUserId());

        // 调用friendApi 保存好友关系
        friendApi.addFriend(UserHolder.getUserId(), fansId);

        // 注册到环信上去
        //huanXinTemplate.contactUsers(UserHolder.getUserId(), fansId);
        return ResponseEntity.ok(null);
    }

    public ResponseEntity removeLike(Long targetUserId) {

        if (friendApi.isFriend(UserHolder.getUserId(), targetUserId)) {
            friendApi.removeSingleFriend(UserHolder.getUserId(), targetUserId);
        }

        userLikeApi.removeLike(UserHolder.getUserId(), targetUserId);
        return ResponseEntity.ok(null);
    }
}
